﻿/*
 * Created by SharpDevelop.
 * User: issuser
 * Date: 2011-1-24
 * Time: 18:40
 * 
 * To change this template use Tools | Options | Coding | Edit Standard Headers.
 */
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Reflection;
using System.Runtime.Serialization;
using System.Xml;

using OSGi.Configuration.BundleManifest;
using OSGi.Console;
using OSGi.Core;
using OSGi.Core.Bundle;
using OSGi.Core.Command;
using OSGi.Core.Event;
using OSGi.Core.Service;
using OSGi.Utility;

namespace OSGi
{
    public enum BundleInitializedState
    {
        Active, Installed
    }
    public enum BundleRuntimeState
    {
        Disposed, Started, Starting, Stopped, Stopping
    }
    public enum BundleStartOptions
    {
        General, Transient
    }
    public enum BundleState
    {
        Active, Installed, Resolved, Starting, Stopping, Uninstalled
    }
    public enum BundleStopOptions
    {
        General, Transient
    }
    public enum CollectionChangedAction
    {
        Add, Remove, Reset
    }
    public enum DefaultBundleState
    {
        Active, Installed
    }
    public enum FrameworkEventType
    {
        Error,
        Info, Started, Starting, Stoppped, Warning
    }
    public enum ResourceLoadMode
    {
        ClassSpace, Local, LocalAndFragment
    }
    public enum ServiceEventType
    {
        Add, Remove
    }

    [Serializable]
    public class BundleEventArgs : EventArgs
    {
        public BundleState CurrentState { get; set; }
        public bool? LazyActivation { get; internal set; }
        public BundleState PreviousState { set; get; }
        public IBundle Target { set; get; }
    }

    [Serializable]
    public class BundleException : Exception
    {
        public BundleException() { }
        public BundleException(string message) : base(message) { }

        public BundleException(string message, Exception innerException)
            : base(message, innerException)
        {
        }

        public BundleException(SerializationInfo info, StreamingContext context)
            : base(info, context)
        {
        }
    }

    public class BundleRuntime
    {
        public BundleRuntime(string pluginsPath) { }
        public BundleRuntime() { }

        public void AddService(System.Type serviceInterface, object serviceInstance)
        {
            throw new NotImplementedException();
        }

        public void AddService<ServiceInterface>(object serviceInstance)
        {
            throw new NotImplementedException();
        }

        public object GetFirstOrDefaultService(System.Type serviceType)
        {
            throw new NotImplementedException();
        }

        public T GetFirstOrDefaultService<T>()
        {
            throw new NotImplementedException();
        }

        public System.Collections.Generic.List<object> GetService(System.Type serviceType)
        {
            throw new NotImplementedException();
        }

        public System.Collections.Generic.List<T> GetService<T>()
        {
            throw new NotImplementedException();
        }

        public void RemoveService(System.Type serviceInterface, object serviceInstance)
        {
            throw new NotImplementedException();
        }

        public void RemoveService<ServiceInterface>(object serviceInstance)
        {
            throw new NotImplementedException();
        }

        public void Start(string[] args)
        {
            throw new NotImplementedException();
        }

        public void Start()
        {
            throw new NotImplementedException();
        }

        public void Stop()
        {
            throw new NotImplementedException();
        }

        public IFramework Framework { get; private set; }
        public string[] StartArgs { get; private set; }
        public BundleRuntimeState State { get; private set; }
    }

    public interface IBundle
    {
        long BundleID { get; }
        IBundleContext Context { get; }
        string Location { get; }
        string Name { get; }
        BundleState State { get; }
        string SymbolicName { get; }
        Version Version { get; }

        int GetBunldeStartLevel();
        System.Type LoadClass(string className);
        object LoadResource(string resourceName, ResourceLoadMode loadMode);
        void Start(BundleStartOptions option);
        void Stop(BundleStopOptions option);
        void Uninstall();
    }

    public interface IBundleActivator
    {
        void Start(IBundleContext context);
        void Stop(IBundleContext context);
    }

    public interface IBundleContext
    {
        IBundle Bundle { get; }
        IFramework Framework { get; }

        event System.EventHandler<BundleEventArgs> BundleStateChanged;
        event System.EventHandler<ExtensionEventArgs> ExtensionChanged;
        event System.EventHandler<ExtensionPointEventArgs> ExtensionPointChanged;
        event System.EventHandler<FrameworkEventArgs> FrameworkStateChanged;
        event System.EventHandler<ServiceEventArgs> ServiceChanged;
        event System.EventHandler<BundleEventArgs> SyncBundleStateChanged;

        void AddExtension(string point, Extension extension);
        void AddService(System.Type serviceType, object serviceInstance);
        void AddService<T>(T serviceInstance);
        IBundle GetBundleByID(long bundleID);
        IBundle GetBundleByLocation(string location);
        IBundle GetBundleBySymbolicName(string symbolicName);
        List<IBundle> GetBundles();
        ExtensionPoint GetExtensionPoint(string point);
        List<ExtensionPoint> GetExtensionPoints();
        List<Extension> GetExtensions(string extensionPoint);
        object GetFirstOrDefaultService(string serviceTypFullName);
        object GetFirstOrDefaultService(System.Type serviceType);
        T GetFirstOrDefaultService<T>();
        List<object> GetService(string serviceTypeName);
        List<object> GetService(System.Type serviceType);
        List<T> GetService<T>();
        IBundle InstallBundle(string location, System.IO.Stream stream);
        IBundle InstallBundle(string location);
        void RemoveExtension(Extension extension);
        void RemoveService(System.Type serviceType, object serviceInstance);
        void RemoveService<T>(object serviceInstance);

    }

    public class Extension
    {
        public IList<XmlNode> Data { get; internal set; }
        public IBundle Owner { get; internal set; }
    }

    public class ExtensionPoint
    {
        public IList<Extension> Extensions { get; internal set; }
        public IBundle Owner { get; internal set; }
        public string Point { get; internal set; }
        public string Schema { get; internal set; }
    }

    public class ExtensionEventArgs : EventArgs
    {
        public CollectionChangedAction Action { get; internal set; }
        public IBundle Bundle { get; internal set; }
        public Extension Extension { get; internal set; }
        public IExtensionManager ExtensionManager { get; internal set; }
        public string ExtensionPoint { get; internal set; }
    }

    public class ExtensionPointEventArgs : EventArgs
    {
        public CollectionChangedAction Action { get; internal set; }
        public IBundle Bundle { get; internal set; }
        public IExtensionManager ExtensionManager { get; internal set; }
        public ExtensionPoint ExtensionPoint { get; internal set; }
    }

    public class FrameworkEventArgs : EventArgs
    {
        public object Data { get; internal set; }
        public FrameworkEventType EventType { get; internal set; }
        public object Target { get; internal set; }
    }

    public class FrameworkOptions
    {
        /// <summary>
        /// 单个Bundle的持久存储的文件名称，保存Bundle私有数据，如上次退出系统时的BundleState。
        /// </summary>
        public string BundlePersistentFileName { set; get; }
        /// <summary>
        /// 是否需要为每个系统用户在Workspace下拷贝一份Bundle数据。
        /// </summary>
        public bool CopyBundleForEachUser { set; get; }
        /// <summary>
        /// Bundle默认状态。如果一个Bundle的Manifest.xml没有指定InitializedState，则框架将使用默认状态 来操作该Bundle。
        /// </summary>
        public DefaultBundleState DefaultBundleState { set; get; }
        /// <summary>
        /// 初始化Framework时，逻辑目录中指定的Features中的Bundle要拷贝到Workspace下， 这个属性指定了要拷贝到Workspace下的文件夹的名称。
        /// </summary>
        public string FeaturesDirectoryName { set; get; }
        /// <summary>
        /// 系统持久存储的文件全路径，保存整个系统的持久存储信息，如：已启动的Bundle列表、已删除的Bundle列表。
        /// </summary>
        public string GlobalPersistentFileFullPath { set; get; }
        /// <summary>
        /// 系统持久存储的文件名称，如果没有指定GlobalPersistentFileFullPath，则根据此名称查找默认路径。
        /// </summary>
        public string GlobalPersistentFileName { set; get; }
        /// <summary>
        /// 逻辑目录的配置文件。
        /// </summary>
        public string LogicDirectoryConfigFile { set; get; }
        /// <summary>
        /// 当拷贝Templae下的Bundle到Workspace下的User目录下时，是否覆盖已有的Bundle目录下的文件。
        /// </summary>
        public bool OverrideExistedBundle { set; get; }
        /// <summary>
        /// 初始化Framework时，逻辑目录中指定的Plugins中的Bundle要拷贝到Workspace下， 这个属性指定了要拷贝到Workspace下的文件夹的名称。
        /// </summary>
        public string PluginsDirectoryName { set; get; }

        public bool RequireLicenseForBundle { get; internal set; }
        /// <summary>
        /// 逻辑目录中的{Startup}对应的物理位置
        /// </summary>
        public string StartUpDir { set; get; }
    }

    public class ServiceEventArgs : EventArgs
    {
        /// <summary>
        /// 服务事件类型。
        /// </summary>
        public ServiceEventType ServiceEventType { set; get; }

        /// <summary>
        /// 服务对象。
        /// </summary>
        public object[] ServiceInstance { set; get; }

        /// <summary>
        /// 注册服务使用的接口类型的FullName
        /// </summary>
        public string[] ServiceType { set; get; }

    }

    public class VersionRange : IEquatable<VersionRange>, IComparable<VersionRange>, IComparable
    {
        public bool IsIncludedEqualMaxVersion { set; get; }
        public bool IsIncludedEqualMinVersion { set; get; }
        public System.Version MaxVersion { set; get; }
        public System.Version MinVersion { set; get; }

        public bool Equals(VersionRange other)
        {
            throw new NotImplementedException();
        }

        public int CompareTo(VersionRange other)
        {
            throw new NotImplementedException();
        }

        public int CompareTo(object obj)
        {
            throw new NotImplementedException();
        }
    }

    namespace Utility
    {
        public class ObservableBindingList<T> : System.ComponentModel.BindingList<T>
        {

        }
    }
    namespace Core
    {
        public interface IFramework
        {
            void AddSystemService(System.Type serviceType, params object[] serviceInstances);
            void AddSystemService(object serviceInstance, params System.Type[] serviceTypes);
            IBundle GetBundle(string location);
            IBundle GetBundleBySymbolicName(string name);
            void RemoveSystemService(System.Type serviceType, object serviceInstance);
            bool RunCommand(string cmd);
            void Start();
            void Stop();
            BundleRepository Bundles { get; }
            ICommandRepository Commands { get; }
            EventManager EventManager { get; }
            bool IsActive { get; }
            FrameworkOptions Options { get; }
            IServiceManager ServiceContainer { get; }
        }

        namespace Bundle
        {
            public class BundleRepository : System.Collections.Generic.List<IBundle>
            {
                public BundleRepository(IFramework framework)
                {
                    throw new NotImplementedException();
                }

                public IBundle GetBundle(string location)
                {
                    throw new NotImplementedException();
                }
                public IBundle GetBundle(long bundleID)
                {
                    throw new NotImplementedException();
                }
                public IBundle GetBundleBySymbolicName(string name)
                {
                    throw new NotImplementedException();
                }
                public IBundle RemoveBundle(string location)
                {
                    throw new NotImplementedException();
                }
                public IBundle RemoveBundle(long bundleID)
                {
                    throw new NotImplementedException();
                }
            }
        }

        namespace Command
        {
            public interface ICommandRepository
            {
                bool Run(string cmd);
                IList<ICommandAdaptor> Commands { get; }
                Dictionary<string, ICommandAdaptor> NamedCommands { get; }
            }
        }

        namespace Event
        {
            public class EventManager : IDisposable
            {
                public IEnumerable<EventHandler<BundleEventArgs>> BundleEventListeners { get; private set; }
                public IEnumerable<EventHandler<FrameworkEventArgs>> FrameworkEventListeners { get; private set; }
                public IEnumerable<EventHandler<BundleEventArgs>> SyncBundleEventListeners { get; private set; }

                public void AddBundleEventListener(System.EventHandler<BundleEventArgs> handler, bool sync)
                {
                    throw new NotImplementedException();
                }

                public void AddFrameworkEventListener(System.EventHandler<FrameworkEventArgs> handler)
                {
                    throw new NotImplementedException();
                }

                public void AddServiceEventListener(System.EventHandler<ServiceEventArgs> handler)
                {
                    throw new NotImplementedException();
                }

                public void DispatchBundleEvent(object sender, BundleEventArgs e)
                {
                    throw new NotImplementedException();
                }

                public void DispatchFrameworkEvent(object sender, FrameworkEventArgs e)
                {
                    throw new NotImplementedException();
                }

                public void DispatchServiceEvent(object sender, ServiceEventArgs e)
                {
                    throw new NotImplementedException();
                }

                public void Dispose()
                {
                    throw new NotImplementedException();
                }

                public void RemoveBundleEventListener(System.EventHandler<BundleEventArgs> handler, bool sync)
                {
                    throw new NotImplementedException();
                }

                public void RemoveFrameworkEventListener(System.EventHandler<FrameworkEventArgs> handler)
                {
                    throw new NotImplementedException();
                }

                public void RemoveServiceEventListener(System.EventHandler<ServiceEventArgs> handler)
                {
                    throw new NotImplementedException();
                }

                public void Start()
                {
                    throw new NotImplementedException();
                }

                public void Stop()
                {
                    throw new NotImplementedException();
                }
            }
        }

        namespace Service
        {
            public class BundleInfo
            {
                public BundleData BundleData { set; get; }
                public BundleState BundleState { set; get; }
            }

            public interface IBundleFactory
            {
                IBundle CreateBundle(BundleData bundleData);
                int InitialBundleId { get; }
                int MaxBundleID { get; }
            }

            public interface IBundleManager
            {
                List<BundleInfo> GetAllBundles();
                IBundle InstallBundle(string location, System.IO.Stream stream);
                IBundle InstallBundle(string location);
                void Start(string bundleSymbolicName, BundleStartOptions option);
                void Start(string bundleSymbolicName);
                void Stop(string bundleSymbolicName, BundleStopOptions option);
                void Stop(string bundleSymbolicName);
                void Uninstall(string bundleSymbolicName);
                void Update(string bundleSymbolicName);
            }

            public interface IBundlePersistent
            {
                object Load(string file);
                void Save(string file);
                void SaveInstallLocation(string path);
                void SaveUnInstallLocation(string path, bool needRemove);
                void SaveUnInstallLocation(string path);
                List<string> InstalledBundleLocation { set; get; }
                List<UnInstallBundleOption> UnInstalledBundleLocation { set; get; }
            }

            public interface IExceptionHandler
            {
                void Handle(object ex);
            }

            public interface IExtensionManager
            {
                void AddExtension(string point, Extension extension);
                ExtensionPoint GetExtensionPoint(string point);
                List<ExtensionPoint> GetExtensionPoints(IBundle bundle);
                List<ExtensionPoint> GetExtensionPoints();
                List<Extension> GetExtensions(string extensionPoint);
                void RemoveExtension(Extension extension);
                ObservableBindingList<ExtensionPoint> ExtensionPoints { get; }
                Dictionary<string, ObservableBindingList<Extension>> Extensions { get; }

                event System.EventHandler<ExtensionEventArgs> ExtensionChanged;
                event System.EventHandler<ExtensionPointEventArgs> ExtensionPointChanged;

            }

            public class UnInstallBundleOption
            {
                public string Location { set; get; }
                public bool NeedRemove { set; get; }
            }

            public interface IServiceManager
            {
                void AddService(IBundle owner, object serviceInstance, params System.Type[] serviceTypes);
                void AddService(IBundle owner, System.Type serviceType, params object[] serviceInstance);
                void AddService<T>(IBundle owner, params object[] serviceInstance);
                object GetFirstOrDefaultService(string serviceType);
                object GetFirstOrDefaultService(System.Type serviceType);
                T GetFirstOrDefaultService<T>();
                List<object> GetService(System.Type serviceType);
                List<object> GetService(string serviceType);
                List<T> GetService<T>();
                void RemoveService(IBundle owner, object serviceInstance);
                void RemoveService(IBundle owner, System.Type serviceType, object serviceInstance);
                void RemoveService<T>(IBundle owner, object serviceInstance);
            }

            public interface IStartLevelManager
            {
                void ChangeBundleStartLevel(IBundle bundle, int startLevel);
                void ChangeStartLevel(int startLevel);
                int InitialBundleStartLevel { set; get; }
                int StartLevel { set; get; }
            }

            public interface ILogicDirService
            {
                IDictionary<string, BundleData> BundleDatas { get; }
                string GlobalPersistentFile { get; }

                BundleData FindBundleContainPath(string path);
                BundleData GetBundleDataByName(string symbolicName);
                string GetBundlePath(string symbolicName);
                bool Init(FrameworkOptions option);
                BundleData RegisterBundle(string bundleDir);
                BundleData RegisterBundle(string bundleDir, System.IO.Stream stream);
            }
        }
    }

    namespace Persistent
    {
        public interface IPersistent
        {
            object Load(string file);
            void Save(string file);
        }

        //		public class BundlePersistentData:IPersistent
        //		{
        //			
        //		}
    }

    namespace Configuration
    {
        public class ManifestParser
        {
            public static BundleData CreateBundleData(System.IO.Stream manifestFileStream)
            {
                throw new NotImplementedException();
            }

            public static BundleData CreateBundleData(string manifestFile)
            {
                throw new NotImplementedException();
            }
        }

        namespace BundleManifest
        {
            public enum ActivatorPolicy
            {
                Immediate, Lazy
            }
            public enum ResolutionType
            {
                Mandatory, Optional
            }
            public class ActivatorData
            {
                public string Type { set; get; }
                public ActivatorPolicy Policy { set; get; }
            }

            public class AssemblyData
            {
                public string Path { set; get; }
                public string[] PathArray { get; internal set; }
                public bool Share { set; get; }
            }
            public class BundleData
            {
                public ActivatorData Activator { set; get; }
                public BundleInfoData BundleInfo { set; get; }
                public List<ExtensionPointData> ExtensionPoints { get; internal set; }
                public List<ExtensionData> Extensions { get; internal set; }
                public string HostBundleSymbolicName { set; get; }
                public VersionRange HostBundleVersion { set; get; }
                public BundleInitializedState? InitializedState { set; get; }
                public string Name { set; get; }
                public string Path { set; get; }
                public RuntimeData Runtime { set; get; }
                public List<ServiceData> Services { set; get; }
                public int? StartLevel { set; get; }
                public string SymbolicName { set; get; }
                public System.Version Version { set; get; }
                public string Xmlns { set; get; }
            }

            public class BundleInfoData
            {
                public string Author { set; get; }
                public string Category { set; get; }
                public string ContactAddress { set; get; }
                public string Copyright { set; get; }
                public string Description { set; get; }
                public string DocumentLocation { set; get; }
                public string ManifestVersion { set; get; }
                public string UpdateLocation { set; get; }
            }

            public class DependencyData
            {
                public string AssemblyName { set; get; }
                public VersionRange AssemblyVersion { set; get; }
                public string BundleSymbolicName { set; get; }
                public VersionRange BundleVersion { set; get; }
                public ResolutionType Resolution { set; get; }
            }

            public class ExtensionData
            {
                public List<XmlNode> ChildNodes { get; internal set; }
                public string Point { set; get; }
            }

            public class ExtensionPointData
            {
                public List<XmlNode> ChildNodes { get; internal set; }
                public string Point { set; get; }
                public string Schema { set; get; }
            }

            public class RuntimeData
            {
                public List<AssemblyData> Assemblies { get; internal set; }
                public List<DependencyData> Dependencies { get; internal set; }
            }
            public class ServiceData
            {
                public string[] Interfaces { set; get; }
                public string Type { set; get; }
            }
        }
    }



    namespace Console
    {
        public interface ICommand
        {
            void Run(string cmd, ICommandContext context);
        }
        public interface ICommandAdaptor
        {
            ICommand Command { get; }
        }
        public interface ICommandContext
        {
            IFramework Framework { get; }
            bool Handled { set; get; }
            string Message { set; get; }
            ReadOnlyCollection<string> Words { get; }
        }
    }

    namespace Loader
    {
        public interface IRuntimeService
        {
            List<Assembly> LoadBundleAssembly(string bundleSymbolicName);
        }
    }
}
